package com.yh.csx.bsf.flow.web.controller.manager;

import com.fasterxml.jackson.core.type.TypeReference;
import com.yh.csx.bsf.core.base.Ref;
import com.yh.csx.bsf.core.util.JsonUtils;
import com.yh.csx.bsf.core.util.StringUtils;
import com.yh.csx.bsf.flow.core.base.FlowException;
import com.yh.csx.bsf.flow.core.base.Model;
import com.yh.csx.bsf.flow.core.base.Variable;
import com.yh.csx.bsf.flow.core.base.Xml;
import com.yh.csx.bsf.flow.core.db.DbHelper;
import com.yh.csx.bsf.flow.dao.dal.t_user_dal;
import com.yh.csx.bsf.flow.dao.model.auto.t_flow_model;
import com.yh.csx.bsf.flow.engine.state.StateEngine;
import com.yh.csx.bsf.flow.provider.enums.FlowStateEnum;
import com.yh.csx.bsf.flow.provider.enums.ModelTypeEnum;
import com.yh.csx.bsf.flow.core.util.XmlUtil;
import com.yh.csx.bsf.flow.dao.dal.t_flow_dal;
import com.yh.csx.bsf.flow.dao.dal.t_model_dal;
import com.yh.csx.bsf.flow.dao.model.auto.t_model_model;
import com.yh.csx.bsf.flow.engine.PaintProvider;
import com.yh.csx.bsf.flow.web.base.SpringMvcController;
import com.yh.csx.bsf.flow.web.base.User;
import com.yh.csx.bsf.flow.web.base.pager.Pager1;
import lombok.val;
import lombok.var;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.servlet.ModelAndView;

import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.stream.Collectors;

/**
 * @author: chejiangyi
 * @version: 2019-10-23 09:41
 **/
@Controller
@RequestMapping("/manager/model")
public class ModelController extends SpringMvcController {
    @RequestMapping("/index")
    public ModelAndView index(String name,String title,String userby,Integer pageindex,Integer pagesize)
    {
        val pageIndex2=(pageindex == null?1:pageindex); val pageSize2=(pagesize == null?10:pagesize);
        html.s2("name",name).s2("title",title).s2("userby",userby).s2("pageindex",pageindex).s2("pagesize",pagesize);
        return pageVisit((m)-> {
                    Ref<Integer> totalSize = new Ref<>(0);
                    val list = DbHelper.get(c->{
                       return new t_model_dal().getPage(c,name,title,userby,0,pageIndex2,pageSize2,totalSize);
                    });
                    new Pager1(pageIndex2,totalSize.getData()).setPageSize(pageSize2).out();
                    request.setAttribute("model",list);
                }
        );
    }
    @RequestMapping("/flow")
    public ModelAndView flow(Integer id)
    {
        val id2 = (id==null?0:id);
        html.s2("id",id2);
        return pageVisit((m)-> {
            var model = DbHelper.get(c -> {
                return new t_model_dal().get(c, id2);
            });
            if (model != null) {
                var xml = new Xml().fromXml(model.getXml());
                html.s2("json",xml.toJson()); ;
            }
            else{
                html.s2("json",null);
            }
        });
    }
    @RequestMapping("/detail")
    public ModelAndView detail(Integer id)
    {
        val id2 = (id==null?0:id);
        html.s2("id",id2);
        return pageVisit((m)-> {
            var model = DbHelper.get(c -> {
                return new t_model_dal().get(c, id2);
            });
            if (model == null) {
                model = new t_model_model();
                var xml = new Xml(new ArrayList<Variable>(),new ArrayList<Model.Node>(),new ArrayList<Model.FormPermission>());
                model.setXml(XmlUtil.serialize(xml));
                model.setModel_type((byte) ModelTypeEnum.common.Value);
            }
            //val mobile_html = DefaultHttpClient.Default.get(model.mobile_form_url);
            //val xml = XmlUtil.deserialize(model.getXml(), new TypeReference<Model.Xml>() {})
            var xml = XmlUtil.deserialize(model.getXml(),Xml.class);
            var paint = new PaintProvider().paint(xml.getNodes());
            html.s2("parint_nodes",JsonUtils.serialize(paint.getNodes()));
            html.s2("parint_links",JsonUtils.serialize(paint.getLinks()));
            html.s2("model", model);
        });
    }
    @RequestMapping("/histroy")
    public ModelAndView histroy(String name)
    {
        html.s2("name",name);
        return pageVisit((m)-> {
            Ref<Integer> totalSize = new Ref<>(0);
            val list = DbHelper.get(c->{
                return new t_model_dal().getHistroy(c,name,0,1000,totalSize);
            });
            request.setAttribute("model",list);
        });
    }
    @RequestMapping("/xml")
    public ModelAndView xml(String json,String xml){
        return jsonVisit((m) -> {
            if(!StringUtils.isEmpty(json)&&!"null".equals(json)) {
                var x = new Xml().fromJson(json);
                x.checkXml();
                return x.toXml();
            }
            if(!StringUtils.isEmpty(xml)&&!"null".equals(xml)) {
                var x = new Xml().fromXml(xml);
                x.checkXml();
                return x.toXml();
            }
            throw new FlowException("请传入json或者xml");
        });
    }

    @RequestMapping("/save")
    public ModelAndView save(Integer id,String name,String title,String xml,String pc_form,String mobile_form,String type,Byte model_type) {
        return jsonVisit((m) -> {
            try {
                var xml1 = XmlUtil.deserialize(xml, Xml.class);
            } catch (Exception e) {
                throw new FlowException("xml 格式错误", e);
            }

            String pc_form_content = JsonUtils.deserialize(pc_form, new TypeReference<String>() {
            });
            String mobile_form_content = JsonUtils.deserialize(mobile_form, new TypeReference<String>() {
            });
            if("debug".equals(type)){
                DbHelper.call((c) -> {
                    var model = new t_model_dal().get(c, id);
                    model.setName(name);model.setTitle(title);model.setPc_form_url(pc_form_content);model.setMobile_form_url(mobile_form_content);
                    model.setUpdate_time(new Date());model.setUpdate_by(User.getCurrent().getUsername());model.setXml(xml);
                    new t_model_dal().edit(c, model);
                });
            }
            else{
                DbHelper.call((c) -> {
                    int version = new t_model_dal().getMaxVersion(c, name);
                    new t_model_dal().add(c, new t_model_model(0, name, title, pc_form_content, mobile_form_content, version + 1, (byte) (version==0?1:0),
                            new Date(), new Date(), User.getCurrent().getUsername(), User.getCurrent().getUsername(), xml,model_type));
                });
            }

            return "ok";
        });
    }
    @RequestMapping("/del")
        public ModelAndView del(String name) {
        return jsonVisit((m) -> {
            DbHelper.call((c) -> {
                val dal = new t_model_dal();
                val model = dal.get(c, name);
                int usedcount = new t_flow_dal().getCountOfUsed(c, model.getName());
                if (usedcount > 0) {
                    throw new FlowException("当前模型还有流程在使用状态,不能删除!");
                }
                new t_model_dal().delete(c, model.getName());
            });
            return "ok";
        });
    }
    @RequestMapping("/setUse")
    public ModelAndView setUse(Integer id) {
        return jsonVisit((m) -> {
            DbHelper.call((c) -> {
                val dal = new t_model_dal();
                val item = dal.get(c,id);
                val oldUse = dal.getUse(c,item.getName());
                dal.setUse(c, id,true);
                if(oldUse!=null&&oldUse.id!=id)
                {dal.setUse(c, oldUse.id,false);}
            });
            return "ok";
        });
    }
        @RequestMapping("/delbyid")
        public ModelAndView delbyid(Integer id) {
            return jsonVisit((m) -> {
                DbHelper.call((c) -> {
                    val dal = new t_model_dal();
                    val model = dal.get(c, id);
                    int usedcount = new t_flow_dal().getCountOfUsed(c, model.getId());
                    if (usedcount > 0) {
                        throw new FlowException("当前模型还有流程在使用状态,不能删除!");
                    }
                    new t_model_dal().delete(c, model.id);
                });
                return "ok";
            });
        }

    @RequestMapping("/createflow")
    public ModelAndView createflow(Integer id)
    {
        val id2 = (id==null?0:id);
        html.s2("id",id2);
        return pageVisit((m)-> {
           DbHelper.noTransactionCall(c-> {
                val dal2 = new t_model_dal();
                var model = dal2.get(c,id);
                val modellist = dal2.getHistroy(c, model.name,0,20,new Ref<Integer>(0));
                html.s2("modelversions",modellist);
                html.s2("title",model.title);
            });
        });
    }

    @RequestMapping("/saveflow")
    public ModelAndView saveflow(Integer modelid,String title, String userno,String variable_json)
    {
        return jsonVisit((m)-> {
            Ref<List<Variable>> variables_new=new Ref<>(null);
            try {
                var json = JsonUtils.deserialize(variable_json, new TypeReference<List<Variable>>() {});
                if(json==null){
                    json = new ArrayList<>();
                }
                json = json.stream().filter(c-> !StringUtils.isEmpty(c.getKey())).collect(Collectors.toList());
                variables_new.setData(json);
            } catch (Exception e) {
                throw new FlowException("json 格式错误", e);
            }
            DbHelper.transaction(()->{
                val flowid= DbHelper.get(c-> {
                    val user = new t_user_dal().getByNo(c,userno);
                    val dal2 = new t_model_dal();
                    val model = dal2.get(c, modelid);
                    val variables = XmlUtil.deserialize(model.getXml(), Xml.class).getVariables();
                    variables.forEach(v -> {
                        var find = variables_new.getData().stream().filter(v2 -> v2.getKey().equals(v.getKey())).findFirst();
                        if (find.isPresent()) {
                            v.setValue(find.get().getValue());
                        }
                    });
                    val dal = new t_flow_dal();
                    val flow = new t_flow_model(0, title, "", "", "",
                            (byte)FlowStateEnum.draft.Value, JsonUtils.serialize(variables),
                            model.id, model.name, model.title, model.version,
                            user.no, new Date(), "系统", new Date(),
                            user.name+"("+User.getCurrent().getUsername()+"代创建)", "");
                    return dal.add2(c, flow);
                });
                new StateEngine().flow((Integer) flowid);
            });
            return true;
        });
    }
//    @RequestMapping("/detail")
//    public ModelAndView detail(Integer id)
//    {
//        html.s2("id",id);
//        return pageVisit((m)-> {
//            var model = DbHelper.get(c -> {
//                return new ModelService().get(c, id);
//            });
//            if (model == null) {
//                model = new t_model_model();
//            }
//            val nodes = JsonUtils.deserialize(model.nodes_define_json, new TypeReference<List<Model.Node>>() {});
//            val variables = JsonUtils.deserialize(model.variable_define_json, new TypeReference<List<Variable>>() {});
//            val formpermission = JsonUtils.deserialize(model.form_permission, new TypeReference<List<Model.FormPermission>>() {});
//            request.setAttribute("model", model);
//            request.setAttribute("variables", variables);
//            request.setAttribute("nodes", nodes);
//            request.setAttribute("formpermission",formpermission);
//        });
//    }
//    @RequestMapping("/save")
//    public ModelAndView save(Integer id,String name,String title,String variable_define_json,String nodes_define_json,String pc_form,String mobile_form,String form_permission_json){
//        return jsonVisit((m)->{
//            List<NodeStr> nodesStrs=null;
//            try {
//                nodesStrs = JsonUtils.deserialize(nodes_define_json, new TypeReference<List<NodeStr>>() {});
//            }catch (Exception e){
//                throw new FlowException("nodes 格式错误");
//            }
//            List<Model.Node> nodes = new ArrayList<>();
//            for(val nodestr:nodesStrs){
//                Model.Node node = new Model.Node();
//                node.setTitle(nodestr.getTitle());node.setTypeEnum(nodestr.getTypeEnum());node.setBeginScript(nodestr.getBeginScript());node.setEndScript(nodestr.getEndScript());
//               node.setRouteScript(nodestr.getRouteScript());node.setStartNotify(nodestr.getStartNotify());node.setEndNotify(nodestr.getEndNotify());
//                try {
//                    var t = JsonUtils.deserialize(nodestr.getApproveUser(), new TypeReference<Model.ApproveUser>() {});
//                    node.setApproveUser(t);
//                }catch (Exception e){
//                    throw new FlowException(nodestr.getTitle()+"审批人 格式错误");
//                }
//                try {
//                    var t = JsonUtils.deserialize(nodestr.getTimeOutRule(), new TypeReference<List<Model.TimeOutRule>>() {});
//                    node.setTimeOutRule(t);
//                }catch (Exception e){
//                    throw new FlowException(nodestr.getTitle()+"超时规则 格式错误");
//                }
//                try {
//                    var t = JsonUtils.deserialize(nodestr.getApproveResults(), new TypeReference<List<String>>() {});
//                    node.setApproveResults(t);
//                }catch (Exception e){
//                    throw new FlowException(nodestr.getTitle()+"审批结果 格式错误");
//                }
//                nodes.add(node);
//            }
//            List<Variable> variables=null;
//            try {
//                variables = JsonUtils.deserialize(variable_define_json, new TypeReference<List<Variable>>() {
//                });
//            }catch (Exception e){
//                throw new FlowException("变量 格式错误");
//            }
//            List<FormPermissionStr> form_permissionStrs =null;List<Model.FormPermission> formPermissions = new ArrayList<>();
//            try {
//                form_permissionStrs= JsonUtils.deserialize(form_permission_json, new TypeReference<List<FormPermissionStr>>() {});
//            }catch (Exception e){
//                throw new FlowException("表单权限 格式错误");
//            }
//            for(val nodestr:form_permissionStrs){
//                Model.FormPermission permission = new Model.FormPermission();permission.setField(nodestr.getField());
//                permission.setNode(nodestr.getNode());permission.setPermissionEnum(nodestr.getPermissionEnum());
//
//                try {
//                    var t = JsonUtils.deserialize(nodestr.getApproveUser(), new TypeReference<Model.ApproveUser>() {});
//                    permission.setApproveUser(t);
//                }catch (Exception e){
//                    throw new FlowException(nodestr.getNode()+" 表单权限 格式错误");
//                }
//                formPermissions.add(permission);
//
//            }
//            String pc_form_content = JsonUtils.deserialize(pc_form, new TypeReference<String>() {});
//            String mobile_form_content = JsonUtils.deserialize(mobile_form, new TypeReference<String>() {});
//            String pc_form_url="";String mobile_form_url="";
//            try {
//                try (val stream = new ByteArrayInputStream(pc_form_content.getBytes())) {
//                    pc_form_url = ContextUtils.getBean(FileProvider.class, false).upload(stream, title);
//                }
//                try (val stream = new ByteArrayInputStream(mobile_form_content.getBytes())) {
//                    mobile_form_url = ContextUtils.getBean(FileProvider.class, false).upload(stream, title);
//                }
//            }catch (Exception e){
//                throw new RuntimeException(e);
//            }
//            val pic_form_url2 =pc_form_url;val mobile_form_url2=mobile_form_url;
//            DbHelper.call((c)->{
//                int version = new t_model_dal().getMaxVersion(c,name);
//                new t_model_dal().add(c,new t_model_model(id,name,title,variable_define_json,JsonUtils.serialize(nodes),pic_form_url2,mobile_form_url2,JsonUtils.serialize(formPermissions),version+1,(byte) 0,
//                        new Date(),new Date(),"",""));
//            });
//
//           return m;
//        });
}
